﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace eComet
{
    public partial class ParamsWin : Form
    {
        public bool debug = false;
        public String[] argv;
        String[] arrExt = ".mp3,.wav,.mp4,.m4a".ToUpper().Split(',');
        Dictionary<string, List<string>> files = new Dictionary<string, List<string>>();

        public ParamsWin()
        {
            InitializeComponent();
        }

        public ParamsWin(String[] argv)
        {
            InitializeComponent();
            this.argv = argv;
        }

        private void ParamsWin_Load(object sender, EventArgs e)
        {
            Thread hilo = new Thread(cargaParams);
            hilo.Start();
        }

        public String getPaths(string[] argv)
        {
            String[] arrDir = ToxUtils.unirParams(argv, "/path");
            return arrDir[1].Replace('¬',' ');
        }

        public void ExitApp()
        {
            if (!debug)
            {
                Thread.Sleep(1000);
                this.Close();
                this.Dispose();
            }
        }

        public Dictionary<string, string> getActions(string[] argv,string paramName)
        {
            Dictionary<string, string> exit = new Dictionary<string, string>();
            int indi = 0;
            while ((indi = ToxUtils.IndexOfArray(argv, paramName, indi)) != -1)
            {
                String[] parms = ToxUtils.unirParams(argv, paramName, indi);
                exit[parms[0]] = parms[1];
                if (indi >= argv.Length)
                    break;
                else
                    indi++;
            }
            return exit;
        }

        public String CleanName(String dirOrFIle)
        {
            string[] separator;
            string archivo;
            int nume = 0;
            if (!ToxUtils.IsDirectory(dirOrFIle))
            {
                archivo = Path.GetFileNameWithoutExtension(dirOrFIle);
            }
            else
            {
                archivo = dirOrFIle.Split('\\').Last();
            }
            archivo = archivo.Replace('_', ' ');
            if (int.TryParse((separator = archivo.Split(' ')).First().Trim(), out nume))
            {
                separator[0] = "";
                archivo = string.Join(" ", separator);
            }
            if (int.TryParse((separator = archivo.Split('.')).First().Trim(), out nume))
            {
                separator[0] = "";
                archivo = string.Join(".", separator);
                archivo = archivo.Substring(1);
            }
            return archivo.Trim();
        }

        public Dictionary<string, string> getActions(Dictionary<string, string> actiones, String fileOrDir, bool isDir)
        {
            int outInt = 0;
            Dictionary<string, string> actions = new Dictionary<string, string>(actiones);
            foreach (String action in actiones.Keys)
            {
                switch (action)
                {
                    case "/setgen":
                        if (isDir)
                        {
                            actions[action] = CleanName(fileOrDir);
                        }
                        else
                        {
                            actions[action] = Path.GetDirectoryName(fileOrDir).Split('\\').Last();
                        }
                        break;
                    case "/setalb":
                        if (isDir)
                        {
                            actions[action] = CleanName(fileOrDir);
                        }
                        else
                        {
                            if (fileOrDir.Contains('-'))
                            {
                                if (!actions[action].Equals(String.Empty))
                                {
                                    if (int.TryParse(actions[action].Trim(), out outInt))
                                    {
                                        string[] arrStr = CleanName(fileOrDir).Split('-');
                                        actions[action] = arrStr[outInt];
                                    }
                                }
                                else
                                {
                                    List<String> datos = new List<String>(CleanName(fileOrDir).Split('-'));
                                    List<String> rem = new List<String>();
                                    foreach (String dato in datos)
                                    {
                                        if (dato.Trim().Equals(String.Empty) || int.TryParse(dato.Trim(), out outInt))
                                        {
                                            rem.Add(dato);
                                        }
                                    }
                                    foreach (String quit in rem)
                                    {
                                        datos.Remove(quit);
                                    }
                                    switch (datos.Count)
                                    {
                                        case 1:
                                            actions[action] = Path.GetDirectoryName(fileOrDir).Split('\\').Last();
                                            break;
                                        case 2:
                                            actions[action] = datos[0];
                                            break;
                                        case 3:
                                            actions[action] = datos[1];
                                            break;
                                    }
                                }
                            }
                            else
                            {
                                actions[action] = Path.GetDirectoryName(fileOrDir).Split('\\').Last();
                            }
                        }
                        break;
                    case "/setart":
                        if (isDir)
                        {
                            actions[action] = CleanName(fileOrDir);
                        }
                        else
                        {
                            if (fileOrDir.Contains('-'))
                            {
                                if (!actions[action].Equals(String.Empty))
                                {
                                    if (int.TryParse(actions[action].Trim(), out outInt))
                                    {
                                        string[] arrStr = CleanName(fileOrDir).Split('-');
                                        actions[action] = arrStr[outInt];
                                    }
                                }
                                else
                                {
                                    List<String> datos = new List<String>(CleanName(fileOrDir).Split('-'));
                                    List<String> rem = new List<String>();
                                    foreach (String dato in datos)
                                    {
                                        if (dato.Trim().Equals(String.Empty) || int.TryParse(dato.Trim(), out outInt))
                                        {
                                            rem.Add(dato);
                                        }
                                    }
                                    foreach (String quit in rem)
                                    {
                                        datos.Remove(quit);
                                    }
                                    switch (datos.Count)
                                    {
                                        case 1:
                                            actions[action] = Path.GetDirectoryName(fileOrDir).Split('\\').Last();
                                            break;
                                        case 2:
                                            actions[action] = datos[0];
                                            break;
                                        case 3:
                                            actions[action] = datos[0];
                                            break;
                                    }
                                }
                            }
                            else
                            {
                                actions[action] = Path.GetDirectoryName(fileOrDir).Split('\\').Last();
                            }
                        }
                        break;
                    case "/setson":
                        if (!isDir)
                        {
                            if (fileOrDir.Contains('-'))
                            {
                                if (!actions[action].Equals(String.Empty))
                                {
                                    if (int.TryParse(actions[action].Trim(), out outInt))
                                    {
                                        string[] arrStr = CleanName(fileOrDir).Split('-');
                                        actions[action] = arrStr[outInt];
                                    }
                                }
                                else
                                {
                                    string[] arrStr = CleanName(fileOrDir).Split('-');
                                    actions[action] = arrStr[arrStr.Length - 1];
                                }
                            }
                            else
                            {
                                actions[action] = CleanName(fileOrDir);
                            }
                        }
                        else
                        {
                            actions[action] = Path.GetDirectoryName(fileOrDir).Split('\\').Last();
                        }
                        break;
                    default:
                        //textBox1.Text = archivo + "\n" + textBox1.Text;
                        break;
                }
            }
            return actions;
        }

        public bool ProcessFiles(Dictionary<string, List<string>> files, Dictionary<string, string> actions)
        {
            bool exit = false;
            if (files.Count > 0)
            {
                richTextBox1.Text = "Processing files ...\n\n";
                string salida;
                foreach (String tipo in files.Keys)
                {
                    switch (tipo)
                    {
                        default:
                            foreach (String archivo in files[tipo])
                            {
                                salida = ToxUtils.EditID3(archivo, actions, tipo);
                                if (salida != null)
                                    richTextBox1.Text += salida + "\n\n";
                            }
                            break;
                    }
                }
                richTextBox1.Text = "FINISHED !!! \n__________\n\n\n" + richTextBox1.Text;
                ExitApp();
            }
            else
            {
                richTextBox1.Text = "No se encontraron archivos validos en la carpeta selecionada\n";
            }
            return exit;
        }

        public void cargaParams()
        {
            try
            {
                richTextBox1.Text = "Analizing files ...\n";
                String paths = getPaths(argv);
                Dictionary<string, string> actions = getActions(argv, "/set");
                if (argv[1].Equals("dir") || argv[1].Equals("file"))
                {
                    foreach (String fileOrDir in paths.Split(';'))
                    {
                        recorreDirs(fileOrDir);
                    }
                    ProcessFiles(files, actions);
                }
                else if (argv[1].Equals("dirs") || argv[1].Equals("files") || argv[1].Equals("dirfile"))
                {
                    foreach (String fileOrDir in paths.Split(';'))
                    {
                        files = new Dictionary<string, List<string>>();
                        recorreDirs(fileOrDir);
                        Dictionary<string, string> actiones = getActions(actions, fileOrDir, ToxUtils.IsDirectory(fileOrDir));
                        ProcessFiles(files, actiones);
                    }
                }
            }
            catch (Exception e)
            {
                richTextBox1.Text = e.Message + "\n\n" + richTextBox1.Text;
            }
        }

        public void AddFile(String file)
        {
            string extension = Path.GetExtension(file).ToUpper();
            if (arrExt.Contains(extension))
            {
                if (!files.ContainsKey(extension))
                {
                    files[extension] = new List<string>();
                }
                files[extension].Add(file);
            }
        }

        public void recorreDirs(String fileOrDir)
        {
                //textBox1.Text += directorio + "\n";
            if (ToxUtils.IsDirectory(fileOrDir))
            {
                foreach (String dir in Directory.GetDirectories(fileOrDir))
                {
                    recorreDirs(dir);
                }
                foreach (String archivo in Directory.GetFiles(fileOrDir))
                {
                    AddFile(archivo);
                }
            }
            else
            {
                AddFile(fileOrDir);
            }
        }
    }
}
